import base64
import json
import pickle

from django import http
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU
from utils.response_code import RETCODE

"""
1.接收数据
2.验证数据
3.判断用户是否登录
4.登录用户操作redis
    4.1 连接redis
    4.2 操作hash
        操作set
    4.3返回响应
5.未登录用户操作cookie
    5.1 组织cookie数据
    5.2 对cookie数据进行编码处理
    5.3 设置cookie数据
    5.4 返回响应
"""
# 添加购物车数据
class CartsView(View):
    def post(self,request):
        # 第二遍
        # 1.接收数据
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected',True)
        # 2验证数据
        if not all([sku_id,count]):
            return http.JsonResponse({'code':RETCODE.PARAMERR,'errmsg':'参数不齐'})
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code':RETCODE.DBERR,'errmsg':'不存在此商品'})
        try:
            count = int(count)
        except:
            count =1
        # 3判断用户是否登录
        user = request.user
        if user.is_authenticated:
            # 4.登录用户操作redis
            #     4.1连接redis
            redis_conn = get_redis_connection('carts')
            #     4.2操作hash
            redis_conn.hset('carts_%s'%user.id,sku_id,count)
            #         操作set
            if selected:
                redis_conn.sadd('selected_%s'%user.id,sku_id)
            #     4.3返回响应
            return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
        else:
            # 5.未登录用户操作cookie
            #     5.1组织cookie数据
            data = request.COOKIES.get('carts')
            if data is not None:
                carts = pickle.loads(base64.b64decode(data))
            else:
                carts={}
            if sku_id in carts:
                original_count = carts[sku_id]['count']
                count += original_count
            carts[int(sku_id)]={
                'count':int(count),
                'selected':selected
            }
            #     5.2对cookie数据进行编码处理
            encode=base64.b64encode(pickle.dumps(carts))
            #     5.3设置cookie数据
            response = http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
            response.set_cookie('carts',encode,max_age=3600*15)
            #     5.4返回响应
            return response


        # # 接收数据
        # data = json.loads(request.body.decode())
        # sku_id = data.get('sku_id')
        # count=data.get('count')
        # selected = data.get('selected',True)
        # # 校验数据
        # if not all([sku_id,count]):
        #     return http.JsonResponse({'code':RETCODE.PARAMERR,'errmsg':'参数不齐'})
        # # 查询商品id是否正确
        # try:
        #     sku = SKU.objects.get(id=sku_id)
        # except SKU.DoesNotExist:
        #     return http.JsonResponse({'code':RETCODE.DBERR,'errmsg':'不存在此商品'})
        # # 查询count是否是int类型,如果不是则改为1
        # try:
        #     count = int(count)
        # except:
        #     count = 1
        #
        # user=request.user
        # # 判断用户是否登陆
        # if user.is_authenticated:
        #     # 用户已经登陆,操作redis
        #     redis_conn = get_redis_connection('carts')
        #     redis_conn.hset('carts_%s' % user.id,sku_id,count)
        #     if selected:
        #         redis_conn.sadd('selected_%s' % user.id,sku_id)
        #     return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
        # else:
        #     # 用户没有登陆,操作cookie
        #     data = request.COOKIES.get('carts')
        #     # 如果缓存中有数据,说明购物车有数据
        #     if data is not None:
        #         decode = base64.b64decode(data)
        #         carts = pickle.loads(decode)
        #     else:
        #         # 缓存中没有数据
        #         carts = {}
        #     # carts = {sku_id:{'selected':selected,'count':count}}
        #     # 如果这个商品在这个购物车数据中,那么就累加
        #     if sku_id in carts:
        #         original_count = carts[sku_id]['count']
        #         count += original_count
        #     # 最后都变成字典
        #     carts[sku_id] = {
        #         'count': count,
        #         'selected': selected
        #     }
        #     # 对cooke进行编码,然后返回给前端
        #     by = pickle.dumps(carts)
        #     encode = base64.b64encode(by)
        #     response = http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
        #     response.set_cookie('carts',encode,max_age=3600)
        #     return response   #
        # 第一遍

    def get(self,request):

        # 第二遍
        # 1.判断用户信息
        user = request.user
        if user.is_authenticated:
            # 2.登录用户获取redis
            #     2.1连接redis
            redis_conn = get_redis_connection('carts')
            #     2.2hash     {sku_id，count}
            sku_id_conut=redis_conn.hgetall('carts_%s'%user.id)

            #         set{sku_id...}
            selected_ids=redis_conn.smembers('selected_%s'%user.id)
            carts={}
            for sku_id,count in sku_id_conut.items():
                if sku_id in selected_ids:
                    selected=True
                else:
                    selected=False
                carts[int(sku_id)]={
                    'count':int(count),
                    'selected':selected
                }

        else:
            # 3.未登录用户获取cookie
            data = request.COOKIES.get('carts')
            #     3.1获取cookie中的carts数据，并进行判断
            if data is not None:
            #         如果有则进行数据解码
                carts=pickle.loads(base64.b64decode(data))
            #         如果没有则初始化一个空的字典
            else:
                carts={}
        # 4.根据id查询商品
        ids = carts.keys()
        skus_list=[]
        for id in ids:

            sku = SKU.objects.get(id=id)

            skus_list.append({
                'id': sku.id,
                'name': sku.name,
                'price': str(sku.price),
                'default_image_url': sku.default_image.url,
                'selected': str(carts[sku.id]['selected']),
                'count': carts[sku.id]['count'],
                'amount': str(carts[sku.id]['count'] * sku.price)
            })
        # 5.将对象转换为字典

        context={
            'cart_skus':skus_list
        }
        return render(request,'cart.html',context)
        # 6.返回响应

        # # 1.判断用户信息
        # user = request.user
        # if user.is_authenticated:
        #     # 2.登录用户获取redis
        #     # 2.1 连接redis
        #     redis_conn = get_redis_connection('carts')
        #     #     2.2  hash{sku_id，count}
        #     sku_id_count = redis_conn.hgetall('carts_%s'%user.id)
        #     #          set{sku_id...}
        #     selected_id  =  redis_conn.smembers('selected_%s'%user.id)
        #     # carts = {sku_id:{selected:True,count:xx},...}
        #     carts={}
        #     for sku_id,count in sku_id_count.items():
        #         if sku_id in selected_id:
        #             selected=True
        #         else:
        #             selected=False
        #         carts[int(sku_id)]={
        #             'count':int(count),
        #             'selected':selected
        #         }
        # else:
        #     # 3.未登录用户获取cookie
        #     data = request.COOKIES.get('carts')
        #     #     3.1获取cookie中的carts数据，并进行判断
        #     if data is not None:
        #     #     如果有则进行数据解码
        #         decode = base64.b64decode(data)
        #         carts = pickle.loads(decode)
        #     #     如果没有则初始化  一个空的字典
        #     else:
        #         carts={}
        # # 4. 根据id查询商品
        # ids = carts.keys()
        # skus_list=[]
        # for id in ids:
        #     sku = SKU.objects.get(id=id)
        # # 5.将对象转换为字典
        #     skus_list.append({
        #         'id': sku.id,
        #         'name': sku.name,
        #         'price': str(sku.price),
        #         'default_image_url': sku.default_image.url,
        #         'selected': str(carts[sku.id]['selected']),
        #         'count': carts[sku.id]['count'],
        #         'amount': str(carts[sku.id]['count'] * sku.price)
        #     })
        # context={
        #     'cart_skus':skus_list
        # }
        # # 6.返回响应
        # return render(request,'cart.html',context)
        # 第一遍


    def put(self,request):
        # 1.接收数据
        data = json.loads(request.body.decode)
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected=data.get('selected')
        # 2.验证数据
        if not all([sku_id,count]):
            return http.JsonResponse({'code':RETCODE.PARAMERR})
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code':RETCODE.DBERR})
        # 3.根据用户信息急性判断
        user = request.user
        if user.is_authenticated:
            # 4.登录用户更新redis
            # 4.1连接redis
            redis_conn = get_redis_connection('carts')
            # 4.2
            #     hash
            redis_conn.hset('carts_%s'%user.id,sku_id,count)
            #     set
            if selected:
                redis_conn.sadd('selected_%s'%user.id,sku_id)
            else:
                redis_conn.srem('selected_%s'%user.id,sku_id)
            # 4.3返回响应
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }
            return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok','cart_sku':cart_sku})
        else:
            # 5.未登录用户更新cookie
            # 5.1读取cookie中的数据并进行判断
            data = request.COOKIES.get('carts')
            if data is not None:
                #         如果有则进行数据解码
                carts = pickle.loads(base64.b64decode(data))
            # 如果没有则初始化一个空的字典
            else:
                carts = {}
            # 5.2更新数据
            if sku_id in carts:
                carts[sku_id]={
                    'count':count,
                    'selected':selected
                }
            # carts = {sku_id: {count: xxx, selected: True}}
            # 5.3对字典编码
            pb = pickle.dumps(carts)
            encode = base64.b64encode(pb)
            cart_sku = {
                'id': sku.id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': sku.price * count,
            }
            #   5.4设置cookie
            response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'cart_sku': cart_sku})
            response.set_cookie('carts', encode, max_age=3600)
            #   5.5返回响应
            return response


        # # 1.接收数据
        # data = json.loads(request.body.decode())
        # sku_id = data.get('sku_id')
        # count = data.get('count')
        # selected = data.get('selected')
        #
        # # 2.验证数据
        # if not all([sku_id,count]):
        #     return http.JsonResponse({'code':RETCODE.PARAMERR})
        # try:
        #     sku = SKU.objects.get(id=sku_id)
        # except SKU.DoesNotExist:
        #     return http.JsonResponse({'code':RETCODE.NODATAERR})
        # try:
        #     count=int(count)
        # except:
        #     return http.JsonResponse({'code':RETCODE.PARAMERR})
        #
        # # 3.根据用户信息进行判断
        # user = request.user
        # if user.is_authenticated:
        #     # 4.登录用户更新redis
        #     #   4.1连接redis
        #     redis_conn = get_redis_connection('carts')
        #     #   4.2hash
        #     redis_conn.hset('carts_%s'%user.id,sku_id,count)
        #     #       set
        #     if selected:
        #         redis_conn.sadd('selected_%s'%user.id,sku_id)
        #     else:
        #         redis_conn.srem('selected_%s'%user.id,sku_id)
        #     cart_sku={
        #         'id': sku_id,
        #         'count': count,
        #         'selected': selected,
        #         'name': sku.name,
        #         'default_image_url': sku.default_image.url,
        #         'price': sku.price,
        #         'amount': sku.price * count,
        #     }
        #     #   4.3返回响应
        #     return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok','cart_sku':cart_sku})
        # else:
        #     # 5.未登录用户更新cookie
        #     #   5.1读取cookie中的数据并进行判断
        #     cookie_str=request.COOKIES.get('carts')
        #     #       如果有则解码
        #     if cookie_str is not None:
        #         carts=pickle.loads(base64.b64decode(cookie_str))
        #     else:
        #         #       如果没有则初始化carts
        #         carts={}
        #     #   5.2更新数据
        #     if sku_id in carts:
        #         carts[sku_id]={
        #             'count':count,
        #             'selected':selected
        #         }
        #     #       carts = {sku_id: {count: xxx, selected: True}}
        #     #   5.3对字典编码
        #     pb=pickle.dumps(carts)
        #     encode=base64.b64encode(pb)
        #     cart_sku={
        #         'id':sku.id,
        #         'count': count,
        #         'selected': selected,
        #         'name': sku.name,
        #         'default_image_url': sku.default_image.url,
        #         'price': sku.price,
        #         'amount': sku.price * count,
        #     }
        #     #   5.4设置cookie
        #     response = http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok','cart_sku':cart_sku})
        #     response.set_cookie('carts',encode,max_age=3600)
        #     #   5.5返回响应
        #     return response


    def delete(self,request):
        # 1.接收数据
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        # 2.验证数据
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code':RETCODE.NODATAERR,'errmsg':'不存在此商品'})
        # 3.获取用户信息，进行用户信息判断
        user = request.user
        if user.is_authenticated:
            # 4.登录用户操作redis
            #     4.1连接redis
            redis_conn =get_redis_connection('carts')
            #     4.2hash
            redis_conn.hdel('carts_%s'%user.id,sku_id)
            #         set
            redis_conn.srem('selected_%s'%user.id,sku_id)
            #     4.3返回响应
            return http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
        else:
            # 5.未登录用户操作cookie
            #     5.1获取cookie中的数据，并进行判断
            cookie_str = request.COOKIES.get('carts')
            #             如果有则解码
            if cookie_str is not None:
                carts=pickle.loads(base64.b64decode(cookie_str))
            #             如果没有则初始化空字典
            else:
                carts={}
            #     5.2删除数据cart = {sku_id: {count: xxx.selected:xxx}}
            if sku_id in carts:
                del carts[sku_id]
            #     5.3编码数据
            encode=base64.b64encode(pickle.dumps(carts))
            #     5.4设置cookie
            response = http.JsonResponse({'code':RETCODE.OK,'errmsg':'ok'})
            response.set_cookie('carts',encode,max_age=3600)
            #     5.5返回响应
            return response